Playwright Zoo Setup for Multi-Domain Testing
This document describes how the Zoo environment is configured to support Playwright testing across multiple domains, specifically for use by both Volpe and Criceto projects.
Overview
The Zoo environment now provides a shared Playwright infrastructure that allows any project (Volpe, Criceto, etc.) to run browser tests against all platform domains using a sidecar architecture.
Architecture
Sidecar Mode
- Playwright Server: Runs in dedicated container (
playwright) - Test Clients: Connect via WebSocket (
ws://playwright:3000) - Browser Execution: Happens in Playwright container with full domain access
- DNS Resolution: All platform domains configured in Playwright container
Container Setup
# Global environment variables automatically added to ALL services
x-default-environment:
&default-environment
- ZOO_ENV=true
playwright:
image: mcr.microsoft.com/playwright:v1.53.2-jammy
container_name: playwright
ports: ["3000:3000"]
environment:
- ZOO_ENV=true # Automatically added to all services
- PLAYWRIGHT_BROWSERS_PATH=/ms-playwright
- NODE_TLS_REJECT_UNAUTHORIZED=0
criceto:
environment:
- ZOO_ENV=true # Automatically added to all services
- PW_TEST_CONNECT_WS_ENDPOINT=ws://playwright:3000
depends_on: [playwright]
Available Domains for Testing
All platform services are accessible via HTTPS through nginx reverse proxy:
| Domain | IP | Service |
|---|---|---|
volpe.localhost | 172.31.0.20 | Digital reader application |
farfalla.localhost | 172.31.0.20 | Core platform backend |
castoro.localhost | 172.31.0.20 | PDF processing service |
coniglio.localhost | 172.31.0.20 | Event tracking and analytics |
medusa.localhost | 172.31.0.20 | Content intake automation |
farfalla-integrations.localhost | 172.31.0.20 | Integration adapters |
farfalla-https-guard.localhost | 172.31.0.20 | HTTPS guard service |
minio.localhost | 172.31.0.19 | Object storage UI |
micelio.localhost | 172.31.0.21 | Smart CDN proxy |
felini.localhost | 172.31.0.21 | Legacy proxy |
criceto.localhost | 172.31.0.21 | Testing toolkit |
Usage for Criceto Team
Prerequisites
-
Start Zoo Environment:
./zoo/zoo.sh up -
Ensure Required Containers Are Running:
- ✅
nginx(reverse proxy for HTTPS domains) - ✅
playwright(browser execution server) - ✅ Target service containers (farfalla, volpe, etc.)
- ✅
Install Playwright in Criceto
Already configured! Criceto package.json includes:
{
"devDependencies": {
"@playwright/test": "^1.53.2"
}
}
Create Playwright Configuration
Create playwright.config.js in Criceto project:
import { defineConfig, devices } from '@playwright/test';
// Environment detection
const isCI = !!process.env.CI;
const isSidecar = !!process.env.PW_TEST_CONNECT_WS_ENDPOINT;
const isZoo = !!process.env.ZOO_ENV || isSidecar;
export default defineConfig({
testDir: './tests/playwright',
forbidOnly: isCI,
retries: isCI ? 2 : 0,
timeout: 30 * 1000,
reporter: [
['list'],
['html', { outputFolder: 'tests/playwright/reports/html' }],
['json', { outputFile: 'tests/playwright/reports/results.json' }],
['junit', { outputFile: 'tests/playwright/reports/results.xml' }]
],
use: {
// Auto-detects base URL based on environment
baseURL: isSidecar ? 'https://farfalla.localhost' : 'http://localhost:8000',
ignoreHTTPSErrors: isZoo,
screenshot: 'only-on-failure',
video: 'retain-on-failure',
trace: 'retain-on-failure',
},
projects: [
{
name: 'chromium-desktop',
use: {
...devices['Desktop Chrome'],
viewport: { width: 1280, height: 720 },
// Zoo-specific browser args (applied automatically in Zoo)
...(isZoo && {
launchOptions: {
args: ['--host-resolver-rules=MAP *.localhost 172.31.0.20']
}
})
},
},
{
name: 'mobile-chrome',
use: {
...devices['Pixel 5'],
viewport: { width: 375, height: 812 },
...(isZoo && {
launchOptions: {
args: ['--host-resolver-rules=MAP *.localhost 172.31.0.20']
}
})
},
},
],
// Only start web server when running locally (not in Zoo sidecar mode)
...(isSidecar || isCI ? {} : {
webServer: {
command: 'php artisan serve',
url: 'http://localhost:8000',
reuseExistingServer: true,
timeout: 120 * 1000,
}
}),
});
Example Test Files
Testing Farfalla Platform
// tests/playwright/farfalla.spec.ts
import { test, expect } from '@playwright/test';
test.describe('Farfalla Platform', () => {
test('should load login page', async ({ page }) => {
await page.goto('https://farfalla.localhost/login');
await expect(page.locator('h1')).toContainText('Login');
});
test('should handle authentication', async ({ page }) => {
await page.goto('https://farfalla.localhost/login');
await page.fill('[name="email"]', 'test@example.com');
await page.fill('[name="password"]', 'password');
await page.click('button[type="submit"]');
// Assert successful login...
});
});
Testing Multiple Domains
// tests/playwright/cross-domain.spec.ts
import { test, expect } from '@playwright/test';
const domains = [
{ name: 'Farfalla', url: 'https://farfalla.localhost' },
{ name: 'Volpe', url: 'https://volpe.localhost' },
{ name: 'Minio', url: 'https://minio.localhost' },
];
domains.forEach(({ name, url }) => {
test(`${name} should be accessible`, async ({ page }) => {
await page.goto(url);
await expect(page).toHaveTitle(/.+/); // Should have some title
});
});
Page Object Model Example
// tests/playwright/pages/FarfallaLoginPage.ts
import { Page, expect } from '@playwright/test';
export class FarfallaLoginPage {
constructor(private page: Page) {}
async goto() {
await this.page.goto('https://farfalla.localhost/login');
}
async login(email: string, password: string) {
await this.page.fill('[name="email"]', email);
await this.page.fill('[name="password"]', password);
await this.page.click('button[type="submit"]');
}
async expectLoginSuccess() {
await expect(this.page).toHaveURL(/dashboard/);
}
}
// Usage in test
test('user login flow', async ({ page }) => {
const loginPage = new FarfallaLoginPage(page);
await loginPage.goto();
await loginPage.login('test@example.com', 'password');
await loginPage.expectLoginSuccess();
});
Running Tests
From Criceto Directory
# Run all Playwright tests
zet
# Run Playwright tests specifically
zex npx playwright test
# Run with UI mode for debugging
zex npx playwright test --ui
# Run specific test file
zex npx playwright test tests/playwright/farfalla.spec.ts
# Run with debug mode
zex npx playwright test --debug
Test Organization
criceto/
├── tests/
│ └── playwright/
│ ├── specs/
│ │ ├── farfalla/
│ │ │ ├── auth.spec.ts
│ │ │ ├── storefront.spec.ts
│ │ │ └── admin.spec.ts
│ │ ├── volpe/
│ │ │ ├── reader.spec.ts
│ │ │ └── annotations.spec.ts
│ │ └── cross-platform/
│ │ ├── integration.spec.ts
│ │ └── workflows.spec.ts
│ ├── pages/
│ │ ├── FarfallaLoginPage.ts
│ │ ├── StorefrontPage.ts
│ │ └── ReaderPage.ts
│ ├── utils/
│ │ ├── test-data.ts
│ │ └── helpers.ts
│ └── reports/
│ ├── html/
│ ├── results.json
│ └── results.xml
└── playwright.config.js
Troubleshooting
Common Issues
-
Tests fail with "net::ERR_CONNECTION_REFUSED"
- ✅ Ensure nginx container is running:
./zoo/zoo.sh status - ✅ Check target service is running (farfalla, volpe, etc.)
- ✅ Ensure nginx container is running:
-
Tests fail with "net::ERR_ADDRESS_UNREACHABLE"
- ✅ Ensure Playwright container is running
- ✅ Restart containers:
./zoo/zoo.sh restart playwright criceto
-
Version mismatch errors
- ✅ All components should use Playwright v1.53.2
- ✅ Update package.json and run
zex npm install
-
DNS resolution issues
- ✅ Playwright container auto-configures all domain mappings
- ✅ Restart if needed:
./zoo/zoo.sh restart playwright
Debug Commands
# Check Zoo container status
./zoo/zoo.sh status
# View Playwright container logs
docker logs playwright
# Test basic connectivity
zex npx playwright test --reporter=verbose
# Check if domains are accessible
curl -k -I https://farfalla.localhost
Environment Variables
When running in Zoo, these are automatically set for all containers:
ZOO_ENV=true- Automatically set for ALL services - Identifies Zoo environment
For services that use Playwright (Volpe, Criceto):
PW_TEST_CONNECT_WS_ENDPOINT=ws://playwright:3000- Enables sidecar modeNODE_TLS_REJECT_UNAUTHORIZED=0- Allows self-signed certificates (Playwright container)
Integration with CI/CD
The same Playwright configuration works in:
- ✅ Local Zoo Environment: Uses sidecar mode
- ✅ GitLab CI: Uses direct container execution
- ✅ Development: Can fallback to local server mode
No code changes needed - environment detection is automatic!
Next Steps for Criceto Team
- Create
playwright.config.jswith the configuration above - Set up test directory structure (
tests/playwright/) - Write first test targeting a specific platform domain
- Run tests:
cd criceto && zet - Iterate and expand test coverage across domains
Support
For issues or questions about the Playwright Zoo setup:
- Check container status:
./zoo/zoo.sh status - View logs:
docker logs playwright - Restart if needed:
./zoo/zoo.sh restart playwright criceto nginx
Ready to test all platform domains! 🚀